package org.ws.httphelper.builder;

import org.ws.httphelper.core.pipeline.HttpHandler;
import org.ws.httphelper.model.config.RequestConfig;
import org.ws.httphelper.model.field.ParamField;
import org.ws.httphelper.model.field.ParseField;
import org.ws.httphelper.model.http.ContentType;
import org.ws.httphelper.model.http.HttpMethod;
import org.ws.httphelper.model.http.ResponseType;

import java.util.Map;

public final class RequestConfigBuilder {
    private RequestConfig requestConfig;
    private RequestTemplateBuilder parentBuilder;

    private RequestConfigBuilder() {
        requestConfig = new RequestConfig();
    }

    private RequestConfigBuilder(RequestConfig parent) {
        requestConfig = new RequestConfig(parent);
    }

    private RequestConfigBuilder(RequestTemplateBuilder parentBuilder) {
        requestConfig = new RequestConfig();
        this.parentBuilder = parentBuilder;
    }

    private RequestConfigBuilder(RequestConfig parent,RequestTemplateBuilder parentBuilder) {
        requestConfig = new RequestConfig(parent);
        this.parentBuilder = parentBuilder;
    }

    public static RequestConfigBuilder builder() {
        return new RequestConfigBuilder();
    }

    public static RequestConfigBuilder builder(RequestConfig parent) {
        return new RequestConfigBuilder(parent);
    }

    protected static RequestConfigBuilder builder(RequestTemplateBuilder parentBuilder) {
        return new RequestConfigBuilder(parentBuilder);
    }

    protected static RequestConfigBuilder builder(RequestConfig parent,RequestTemplateBuilder parentBuilder) {
        return new RequestConfigBuilder(parent,parentBuilder);
    }

    public RequestConfigBuilder method(HttpMethod method) {
        requestConfig.setMethod(method);
        return this;
    }

    public RequestConfigBuilder defaultHeaders(Map<String, String> defaultHeaders) {
        requestConfig.setDefaultHeaders(defaultHeaders);
        return this;
    }

    public RequestConfigBuilder addDefaultHeader(String name, String value) {
        requestConfig.addDefaultHeader(name,value);
        return this;
    }

    public RequestConfigBuilder defaultCookers(Map<String, String> defaultCookers) {
        requestConfig.setDefaultCookers(defaultCookers);
        return this;
    }

    public RequestConfigBuilder addDefaultCookie(String name, String value) {
        requestConfig.addDefaultCookie(name,value);
        return this;
    }

    public RequestConfigBuilder defaultParams(Map<String, Object> defaultParams) {
        requestConfig.setDefaultParams(defaultParams);
        return this;
    }

    public RequestConfigBuilder addDefaultParam(String name, Object value) {
        requestConfig.addDefaultParams(name,value);
        return this;
    }

    public RequestConfigBuilder addHandler(HttpHandler httpHandler) {
        requestConfig.getHttpPipeline().addLast(httpHandler);
        return this;
    }

    public RequestConfigBuilder addHandler(HttpHandler... handlers) {
        requestConfig.getHttpPipeline().addLast(handlers);
        return this;
    }

    public RequestConfigBuilder paramFields(Map<String, ParamField> paramFields) {
        requestConfig.setParamFields(paramFields);
        return this;
    }

    public RequestConfigBuilder addParamFields(ParamField paramField) {
        requestConfig.addParamField(paramField);
        return this;
    }

    public RequestConfigBuilder rootUrl(String rootUrl) {
        requestConfig.setRootUrl(rootUrl);
        return this;
    }

    public RequestConfigBuilder charset(String charset) {
        requestConfig.setCharset(charset);
        return this;
    }

    public RequestConfigBuilder contentType(ContentType contentType) {
        requestConfig.setContentType(contentType);
        return this;
    }

    public RequestConfigBuilder responseType(ResponseType responseType) {
        requestConfig.setResponseType(responseType);
        return this;
    }

    public RequestConfigBuilder parseHtmlFields(Map<String, ParseField> parseHtmlFields) {
        requestConfig.setParseHtmlFields(parseHtmlFields);
        return this;
    }

    public RequestConfigBuilder addParseHtmlFields(ParseField parseField) {
        requestConfig.addParseHtmlField(parseField);
        return this;
    }

    public ClientConfigBuilder clientConfig(){
        if(this.parentBuilder == null){
            return null;
        }
        this.parentBuilder.requestConfig(build());
        return this.parentBuilder.buildClientConfig();
    }

    public RequestTemplateBuilder end(){
        if(this.parentBuilder == null){
            return null;
        }
        this.parentBuilder.requestConfig(build());
        return this.parentBuilder;
    }

    public RequestConfig build() {
        return requestConfig;
    }
}
